package com.imooc.utils;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * @author imooc
 * @version V1.0
 * @Title: CookieUtils.java
 * @Package com.imooc.utils
 * @Description: Cookie 工具类 Copyright: Copyright (c) Company: www.imooc.com
 */
public final class CookieUtils {

  final static Logger logger = LoggerFactory.getLogger(CookieUtils.class);

  /**
   * @param request
   * @param cookieName
   * @return
   * @Description: 得到Cookie的值, 不编码
   */
  public static String getCookieValue(HttpServletRequest request, String cookieName) {
    return getCookieValue(request, cookieName, false);
  }

  /**
   * @param request
   * @param cookieName
   * @param isDecoder
   * @return
   * @Description: 得到Cookie的值
   */
  public static String getCookieValue(HttpServletRequest request, String cookieName,
      boolean isDecoder) {
    Cookie[] cookieList = request.getCookies();
    if (cookieList == null || cookieName == null) {
      return null;
    }
    String retValue = null;
    try {
      for (int i = 0; i < cookieList.length; i++) {
        if (cookieList[i].getName().equals(cookieName)) {
          if (isDecoder) {
            retValue = URLDecoder.decode(cookieList[i].getValue(), "UTF-8");
          } else {
            retValue = cookieList[i].getValue();
          }
          break;
        }
      }
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    }
    return retValue;
  }

  /**
   * @param request
   * @param cookieName
   * @param encodeString
   * @return
   * @Description: 得到Cookie的值
   */
  public static String getCookieValue(HttpServletRequest request, String cookieName,
      String encodeString) {
    Cookie[] cookieList = request.getCookies();
    if (cookieList == null || cookieName == null) {
      return null;
    }
    String retValue = null;
    try {
      for (int i = 0; i < cookieList.length; i++) {
        if (cookieList[i].getName().equals(cookieName)) {
          retValue = URLDecoder.decode(cookieList[i].getValue(), encodeString);
          break;
        }
      }
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    }
    return retValue;
  }

  /**
   * @param request
   * @param response
   * @param cookieName
   * @param cookieValue
   * @Description: 设置Cookie的值 不设置生效时间默认浏览器关闭即失效,也不编码
   */
  public static void setCookie(HttpServletRequest request, HttpServletResponse response,
      String cookieName,
      String cookieValue) {
    setCookie(request, response, cookieName, cookieValue, -1);
  }

  /**
   * @param request
   * @param response
   * @param cookieName
   * @param cookieValue
   * @param cookieMaxage
   * @Description: 设置Cookie的值 在指定时间内生效,但不编码
   */
  public static void setCookie(HttpServletRequest request, HttpServletResponse response,
      String cookieName,
      String cookieValue, int cookieMaxage) {
    setCookie(request, response, cookieName, cookieValue, cookieMaxage, false);
  }

  /**
   * @param request
   * @param response
   * @param cookieName
   * @param cookieValue
   * @param isEncode
   * @Description: 设置Cookie的值 不设置生效时间,但编码 在服务器被创建，返回给客户端，并且保存客户端 如果设置了SETMAXAGE(int
   * seconds)，会把cookie保存在客户端的硬盘中 如果没有设置，会默认把cookie保存在浏览器的内存中 一旦设置setPath()：只能通过设置的路径才能获取到当前的cookie信息
   */
  public static void setCookie(HttpServletRequest request, HttpServletResponse response,
      String cookieName,
      String cookieValue, boolean isEncode) {
    setCookie(request, response, cookieName, cookieValue, -1, isEncode);
  }

  /**
   * @param request
   * @param response
   * @param cookieName
   * @param cookieValue
   * @param cookieMaxage
   * @param isEncode
   * @Description: 设置Cookie的值 在指定时间内生效, 编码参数
   */
  public static void setCookie(HttpServletRequest request, HttpServletResponse response,
      String cookieName,
      String cookieValue, int cookieMaxage, boolean isEncode) {
    doSetCookie(request, response, cookieName, cookieValue, cookieMaxage, isEncode);
  }

  /**
   * @param request
   * @param response
   * @param cookieName
   * @param cookieValue
   * @param cookieMaxage
   * @param encodeString
   * @Description: 设置Cookie的值 在指定时间内生效, 编码参数(指定编码)
   */
  public static void setCookie(HttpServletRequest request, HttpServletResponse response,
      String cookieName,
      String cookieValue, int cookieMaxage, String encodeString) {
    doSetCookie(request, response, cookieName, cookieValue, cookieMaxage, encodeString);
  }

  /**
   * @param request
   * @param response
   * @param cookieName
   * @Description: 删除Cookie带cookie域名
   */
  public static void deleteCookie(HttpServletRequest request, HttpServletResponse response,
      String cookieName) {
    doSetCookie(request, response, cookieName, null, -1, false);
//        doSetCookie(request, response, cookieName, "", -1, false);
  }


  /**
   * @param request
   * @param response
   * @param cookieName
   * @param cookieValue
   * @param cookieMaxage cookie生效的最大秒数
   * @param isEncode
   * @Description: 设置Cookie的值，并使其在指定时间内生效
   */
  private static final void doSetCookie(HttpServletRequest request, HttpServletResponse response,
      String cookieName, String cookieValue, int cookieMaxage, boolean isEncode) {
    try {
      if (cookieValue == null) {
        cookieValue = "";
      } else if (isEncode) {
        cookieValue = URLEncoder.encode(cookieValue, "utf-8");
      }
      Cookie cookie = new Cookie(cookieName, cookieValue);
        if (cookieMaxage > 0) {
            cookie.setMaxAge(cookieMaxage);
        }
      if (null != request) {// 设置域名的cookie
        String domainName = getDomainName(request);
        logger.info("========== domainName: {} ==========", domainName);
        if (!"localhost".equals(domainName)) {
          cookie.setDomain(domainName);
        }
      }
      cookie.setPath("/");
      response.addCookie(cookie);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  /**
   * @param request
   * @param response
   * @param cookieName
   * @param cookieValue
   * @param cookieMaxage cookie生效的最大秒数
   * @param encodeString
   * @Description: 设置Cookie的值，并使其在指定时间内生效
   */
  private static final void doSetCookie(HttpServletRequest request, HttpServletResponse response,
      String cookieName, String cookieValue, int cookieMaxage, String encodeString) {
    try {
      if (cookieValue == null) {
        cookieValue = "";
      } else {
        cookieValue = URLEncoder.encode(cookieValue, encodeString);
      }
      Cookie cookie = new Cookie(cookieName, cookieValue);
        if (cookieMaxage > 0) {
            cookie.setMaxAge(cookieMaxage);
        }
      if (null != request) {// 设置域名的cookie
        String domainName = getDomainName(request);
        logger.info("========== domainName: {} ==========", domainName);
        if (!"localhost".equals(domainName)) {
          cookie.setDomain(domainName);
        }
      }
      cookie.setPath("/");
      response.addCookie(cookie);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  /**
   * @return
   * @Description: 得到cookie的域名
   */
  private static final String getDomainName(HttpServletRequest request) {
    String domainName = null;

    String serverName = request.getRequestURL().toString();
    if (serverName == null || serverName.equals("")) {
      domainName = "";
    } else {
      serverName = serverName.toLowerCase();
      serverName = serverName.substring(7);
      final int end = serverName.indexOf("/");
      serverName = serverName.substring(0, end);
      if (serverName.indexOf(":") > 0) {
        String[] ary = serverName.split("\\:");
        serverName = ary[0];
      }

      final String[] domains = serverName.split("\\.");
      int len = domains.length;
      if (len > 3 && !isIp(serverName)) {
        // www.xxx.com.cn
        domainName = "." + domains[len - 3] + "." + domains[len - 2] + "." + domains[len - 1];
      } else if (len <= 3 && len > 1) {
        // xxx.com or xxx.cn
        domainName = "." + domains[len - 2] + "." + domains[len - 1];
      } else {
        domainName = serverName;
      }
    }
    return domainName;
  }

  public static String trimSpaces(String IP) {//去掉IP字符串前后所有的空格
    while (IP.startsWith(" ")) {
      IP = IP.substring(1).trim();
    }
    while (IP.endsWith(" ")) {
      IP = IP.substring(0, IP.length() - 1).trim();
    }
    return IP;
  }

  public static boolean isIp(String IP) {//判断是否是一个IP
    boolean b = false;
    IP = trimSpaces(IP);
    if (IP.matches("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}")) {
      String[] s = IP.split("\\.");
        if (Integer.parseInt(s[0]) < 255) {
            if (Integer.parseInt(s[1]) < 255) {
                if (Integer.parseInt(s[2]) < 255) {
                    if (Integer.parseInt(s[3]) < 255) {
                        b = true;
                    }
                }
            }
        }
    }
    return b;
  }

}
